package com.sea.base.floating

import android.annotation.SuppressLint
import com.sea.base.ext.global.getCurrentMillis
import com.sea.base.ext.global.postMainDelayed
import com.sea.base.ext.global.removeGlobalRunnable
import com.sea.base.ext.global.removeIfIterator
import com.sea.base.utils.ActivityStackManager
import java.util.LinkedList

/**
 * 单例悬浮排队队列，app可见才会show，请使用[GlobalFloatingQueueItem]
 */
object GlobalFloatingQueueManager {
    private val list = LinkedList<GlobalFloatingQueueItem>()

    @SuppressLint("StaticFieldLeak")
    private var currentShowItem: GlobalFloatingQueueItem? = null
    private var currentDelayRun: Runnable? = null

    /**
     * 请使用[GlobalFloatingQueueItem.addItemQueue]
     */
    fun addItemQueue(item: GlobalFloatingQueueItem) {
        if (!list.contains(item)) {
            list.add(item)
        }
        checkNext()
    }

    private fun checkNext() {
        val now = getCurrentMillis()
        list.removeIfIterator {
            val isTimeout = now - it.createTime > it.timeoutMillis
            if (isTimeout) {
                it.onTimeoutCall?.invoke()
            }
            isTimeout
        }
        if (currentShowItem == null) {
            currentShowItem = list.firstOrNull()
            currentShowItem?.let { item ->
                ActivityStackManager.doOnAppVisible {
                    GlobalFloatingUtil.showAppFloating(item.view)
                    item.onShowCall?.invoke()
                    postMainDelayed(item.showMillis, Runnable {
                        hideItem(item)
                    }.also {
                        currentDelayRun = it
                    })
                }
            }
        }
    }

    /**
     * 请使用[GlobalFloatingQueueItem.hideItem]
     */
    fun hideItem(item: GlobalFloatingQueueItem) {
        GlobalFloatingUtil.hideAppFloating(item.view)
        list.remove(item)
        item.onHideCall?.invoke()
        if (currentShowItem == item) {
            currentDelayRun?.let {
                removeGlobalRunnable(it)
                currentDelayRun = null
            }
            currentShowItem = null
        }
        checkNext()
    }
}